#pragma once

#include "Piece.h"

enum class MoveType : byte
{
	Normal,
	Capture,
	Castle,
	EnPassant
};

enum StateFlags : uint
{
	NONE = 0,

	//////////////////////////////////////////////////////////////////////////
	// Persistent States
	//////////////////////////////////////////////////////////////////////////

	// Move Conditions
	BLACK_CHECK =		0x00000001,
	BLACK_MATE =		0x00000002,
	WHITE_CHECK =		0x00000004,
	WHITE_MATE =		0x00000008,

	// Castling Conditions
	WHITE_CASTLED =		0x00000010,
	BLACK_CASTLED =		0x00000020,

	B_L_ROOK_MOVED =	0x00000040,
	B_R_ROOK_MOVED =	0x00000080,
	B_KING_MOVED =		0x00000100,

	W_L_ROOK_MOVED =	0x00000200,
	W_R_ROOK_MOVED =	0x00000400,
	W_KING_MOVED =		0x00000800,

	STALEMATE =			0x00001000,

	//////////////////////////////////////////////////////////////////////////

	//////////////////////////////////////////////////////////////////////////
	// Temporal Flags
	//////////////////////////////////////////////////////////////////////////
	
	EN_PASSANT =		0x00002000,
	PROMOTED =			0x00004000,
	CASTLED =			0x00008000

	//////////////////////////////////////////////////////////////////////////
};


struct Move 
{
	// 4 bytes
	Piece Piece1;
	byte SrcPos1;
	byte DestPos1;
	
	// 2 bytes
	byte SrcPos2;
	byte DestPos2;

	// 2 bytes
	PieceType Captured;
	MoveType Type;

	// 5 bytes
	uint Flags;
	byte EnPassantPosition;

	// 2 bytes
	byte NumWhiteMoves = 0;
	byte NumBlackMoves = 0;

	byte Padding[1];

	// Total: 16 bytes
	Move() : Flags(NONE) { }
	Move(Piece p, byte srcPos, byte dstPos, uint flags = NONE)
		: Piece1(p), SrcPos1(srcPos), DestPos1(dstPos), Type(MoveType::Normal), Flags(flags) { }
	Move(Piece p, byte srcPos1, byte dstPos1, byte srcPos2, byte dstPos2, MoveType type = MoveType::Castle, uint flags = CASTLED)
		: Piece1(p), SrcPos1(srcPos1), DestPos1(dstPos1), SrcPos2(srcPos2), DestPos2(dstPos2), Type(type), Flags(flags) { }
	Move(Piece p, Piece captured, byte srcPos1, byte dstPos1, uint flags = NONE, byte srcPos2 = 0, byte dstPos2 = 0)
		: Piece1(p), Captured(captured.Type), SrcPos1(srcPos1), DestPos1(dstPos1), 
		  SrcPos2(srcPos2), DestPos2(dstPos2), Type(MoveType::Capture), Flags(flags) { }
};